/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.oa.service;

import com.google.common.collect.Maps;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.act.service.ActTaskService;
import com.thinkgem.jeesite.modules.act.utils.ActUtils;
import com.thinkgem.jeesite.modules.oa.dao.BudgetDao;
import com.thinkgem.jeesite.modules.oa.dao.TestAuditDao;
import com.thinkgem.jeesite.modules.oa.entity.*;
import com.thinkgem.jeesite.modules.sys.dao.RoleDao;
import com.thinkgem.jeesite.modules.sys.dao.UserDao;
import com.thinkgem.jeesite.modules.sys.entity.Category;
import com.thinkgem.jeesite.modules.sys.entity.Office;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.SystemService;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 审批Service
 * @author thinkgem
 * @version 2014-05-16
 */
@Service
@Transactional(readOnly = true)
public class BudgetService extends CrudService<BudgetDao, Budget> {

	@Autowired
	private ActTaskService actTaskService;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private SystemService systemService;
	@Autowired
	private SubjectService subjectService;
	public Budget getByProcInsId(String procInsId) {
		return dao.getByProcInsId(procInsId);
	}
	public List<Subject> findBudgetSubject(Budget budget){
		return dao.findBudgetSubject(budget);
	}
	public List<Subject> findBudgetSubjectHistroy(Budget budget){
		return dao.findBudgetSubjectHistory(budget);
	}
	public List<Subject> findThirdLevelStatistics(Budget budget){
		return dao.findThirdLevelStatistics(budget);
	}
	public List<Subject> findClassifyStatistics(Budget budget){
		return dao.findClassifyStatistics(budget);
	}
	public Page<Budget> findPage(Page<Budget> page, Budget budget) {
		List<Subject> subjects = subjectService.findList(new Subject());
		budget.setPage(page);
		List<Budget> budgets = dao.findList(budget);
		for(Budget b:budgets){
			List<Subject> subjectList = dao.findBudgetSubject(b);
			if(subjectList != null && subjectList.size()>0){
				b.setSubjectList(subjectList);
			}else {
				b.setSubjectList(subjects);
			}
		}
		page.setList(budgets);
		Double budgetSum = dao.findBudgetSum(budget);
		page.setValue1(budgetSum);
		return page;
	}
	public List<Budget> findBudgetListDetail(Budget budget) {
		List<Subject> subjects = subjectService.findList(new Subject());
		List<Budget> budgets = dao.findList(budget);
		for(Budget b:budgets){
			List<Subject> subjectList = dao.findBudgetSubject(b);
			if(subjectList != null && subjectList.size()>0){
				b.setSubjectList(subjectList);
			}else {
				b.setSubjectList(subjects);
			}
		}
		return budgets;
	}
	public Page<Budget> getOfficeAndBelowBudgetList(Page<Budget> page,String office,Budget param){
		List<Subject> subjects = subjectService.findList(new Subject());

		Budget budget = new Budget();
		budget.setPage(page);
		String officeLike = "%,"+office+",%";
		budget.setOfficeId(office);
		budget.setOfficeLike(officeLike);
		budget.setOffice(param.getOffice());
		budget.setTitle(param.getTitle());
		budget.setAnnual(param.getAnnual());
		List<Budget> budgets = dao.getBudgetList(budget);
		for(Budget b:budgets){
			List<Subject> subjectList = dao.findBudgetSubject(b);
			if(subjectList != null && subjectList.size()>0){
				b.setSubjectList(subjectList);
			}else {
				b.setSubjectList(subjects);
			}
		}
		page.setList(budgets);
		Double budgetSum = dao.getBudgetListSum(budget);
		page.setValue1(budgetSum);
		return page;
	}
	/**
	 * 查询某个部门及其以下的预算
	 * @param office
	 * @return
	 */
	public Page<Budget> getOfficeBudgetList(Page<Budget> page,String office,Budget param){
		List<Subject> subjects = subjectService.findList(new Subject());
		Budget budget = new Budget();
		budget.setPage(page);
		budget.setOfficeId(office);
		budget.setOffice(param.getOffice());
		budget.setTitle(param.getTitle());
		budget.setAnnual(param.getAnnual());
		List<Budget> budgets = dao.getOfficeBudgetList(budget);
		for(Budget b:budgets){
			List<Subject> subjectList = dao.findBudgetSubject(b);
			if(subjectList != null && subjectList.size()>0){
				b.setSubjectList(subjectList);
			}else {
				b.setSubjectList(subjects);
			}
		}
		Double budgetSum = dao.getOfficeBudgetListSum(budget);
		page.setValue1(budgetSum);
		page.setList(budgets);
		return page;
	}

	/**
	 * 查询由该用户发布的预算
	 * @param page
	 * @param userId
     * @return
     */
	public Page<Budget> getBudgetListByCreateUser(Page<Budget> page,String userId,Budget param){
		List<Subject> subjects = subjectService.findList(new Subject());
		Budget budget = new Budget();
		budget.setPage(page);
		budget.setCreateBy(new User(userId));
		budget.setPage(page);
		budget.setTitle(param.getTitle());
		budget.setAnnual(param.getAnnual());
		List<Budget> budgets = dao.getBudgetListByCreateUser(budget);
		for(Budget b:budgets){
			List<Subject> subjectList = dao.findBudgetSubject(b);
			if(subjectList != null && subjectList.size()>0){
				b.setSubjectList(subjectList);
			}else {
				b.setSubjectList(subjects);
			}
		}
		page.setList(budgets);
		Double budgetSum = dao.getBudgetListByCreateUserSum(budget);
		page.setValue1(budgetSum);
		return page;
	}

	/**
	 * 批量修改预算
	 * @param budgetBatch
	 */
	@Transactional(readOnly = false)
	public void saveBudgetSubjectBatch(BudgetBatch budgetBatch){
		for(Budget budget:budgetBatch.getBudgets()){
			budget.preUpdate();
			dao.updateAggregate(budget);
			dao.deleteBudgetSubject(budget);
			List<BudgetSubject> budgetSubjectList = new ArrayList<BudgetSubject>();
			for(Subject s:budget.getSubjectList()){
				if(StringUtils.isNoneBlank(s.getId())) {
					BudgetSubject budgetSubject = new BudgetSubject();
					budgetSubject.setBudget(budget);
					budgetSubject.setSubject(s);
					budgetSubject.setFee(s.getMoney());
					budgetSubjectList.add(budgetSubject);
					budgetSubject.preInsert();
				}
			}
			dao.insertBudgetSubject(budgetSubjectList);
		}
	}
	/**
	 * 审核新增或编辑
	 * @param budget
	 */
	@Transactional(readOnly = false)
	public void save(Budget budget) {
		// 申请发起
		if (StringUtils.isBlank(budget.getId())){
			budget.preInsert();
			String loginName = UserUtils.getUser().getLoginName();
			User user = systemService.getUserByLoginName(loginName);
			budget.setOffice(user.getOffice());
			dao.insert(budget);
			List<BudgetSubject> budgetSubjectList = new ArrayList<BudgetSubject>();
			for(Subject s:budget.getSubjectList()){
				if(StringUtils.isNoneBlank(s.getId())) {
					BudgetSubject budgetSubject = new BudgetSubject();
					budgetSubject.setBudget(budget);
					budgetSubject.setSubject(s);
					budgetSubject.setFee(s.getMoney());
					budgetSubject.setDetails(s.getDetails());
					budgetSubjectList.add(budgetSubject);
					budgetSubject.preInsert();
				}
			}
			dao.insertBudgetSubject(budgetSubjectList);
			dao.insertBudgetSubjectHistory(budgetSubjectList);
			if(budget.getActionType() == null || !"save".equals(budget.getActionType())) {
				/*List<User> leaders = systemService.findOfficeManager(user);
				if (leaders == null || leaders.size() == 0) {
					throw new RuntimeException("没有下级处理人");
				}
				String users = "";
				for (User u : leaders) {
					users = users + u.getLoginName() + ",";
				}*/
				Map<String, Object> vars = Maps.newHashMap();
				vars.put("user", budget.getProcessUser().getLoginName());
				actTaskService.startProcess(ActUtils.PD_TEST_BUDGET[0], ActUtils.PD_TEST_BUDGET[1], budget.getId(), budget.getTitle(), vars);
			}
		}
		// 重新编辑申请
		else{
			budget.preUpdate();
			dao.update(budget);
			List<BudgetSubject> budgetSubjectList = new ArrayList<BudgetSubject>();
			for(Subject s:budget.getSubjectList()){
				if(StringUtils.isNoneBlank(s.getId())) {
					BudgetSubject budgetSubject = new BudgetSubject();
					budgetSubject.setBudget(budget);
					budgetSubject.setSubject(s);
					budgetSubject.setFee(s.getMoney());
                    budgetSubject.setDetails(s.getDetails());
                    budgetSubjectList.add(budgetSubject);
					budgetSubject.preInsert();
				}
			}
			dao.deleteBudgetSubject(budget);
			dao.insertBudgetSubject(budgetSubjectList);
			if(budget.getActionType() == null || !"save".equals(budget.getActionType())) {
				// 完成流程任务
				/*String loginName = UserUtils.getUser().getLoginName();//ObjectUtils.toString(UserUtils.getUser().getId())
				User user = systemService.getUserByLoginName(loginName);
				List<User> leaders = systemService.findOfficeManager(user);
				if (leaders == null || leaders.size() == 0) {
					throw new RuntimeException("没有下级处理人");
				}
				String users = "";
				for (User u : leaders) {
					users = users + u.getLoginName() + ",";
				}*/
				Map<String, Object> vars = Maps.newHashMap();
				vars.put("user", budget.getProcessUser().getLoginName());
				if(budget.getAct() != null && StringUtils.isNoneBlank(budget.getAct().getTaskId())) {
					budget.getAct().setComment(("yes".equals(budget.getAct().getFlag()) ? "[重申] " : "[销毁] "));//+budget.getAct().getComment());
					vars.put("pass", "yes".equals(budget.getAct().getFlag()) ? "1" : "0");
					actTaskService.complete(budget.getAct().getTaskId(), budget.getAct().getProcInsId(), budget.getAct().getComment(), budget.getTitle(), vars);
				}else {
					actTaskService.startProcess(ActUtils.PD_TEST_BUDGET[0], ActUtils.PD_TEST_BUDGET[1], budget.getId(), budget.getTitle(), vars);
				}
			}
		}
	}

	/**
	 * 审核审批保存
	 * @param budget
	 */
	@Transactional(readOnly = false)
	public void auditSave(Budget budget) {
		String comment = budget.getAct().getComment();
		if(comment == null){
			comment = "";
		}
		// 设置意见
		budget.getAct().setComment(("yes".equals(budget.getAct().getFlag())?"[同意] ":"[驳回] ")+comment);
		budget.preUpdate();
		
		// 对不同环节的业务逻辑进行操作
		String taskDefKey = budget.getAct().getTaskDefKey();
		Map<String, Object> vars = Maps.newHashMap();

		// 审核环节
		if ("audit".equals(taskDefKey)){
			budget.setDuatyText(budget.getAct().getComment());
			//审核通过到下级处理人
			if("yes".equals(budget.getAct().getFlag())) {
				/*List<User> auditors = systemService.findUserByUserType("1");
				if(auditors == null || auditors.size() == 0){
					throw new RuntimeException("没有下级处理人!");
				}
				String users = "";
				for (User auditor : auditors) {
					users = users + auditor.getLoginName() + ",";
				}*/
				vars.put("user", budget.getProcessUser().getLoginName());
			}
			dao.updateDuatyText(budget);
		}
		else if ("audit2".equals(taskDefKey)){
			budget.setAuditText(budget.getAct().getComment());
			dao.updateAuditText(budget);
		}
		// 未知环节，直接返回
		else{
			return;
		}
		// 提交流程任务
		vars.put("pass", "yes".equals(budget.getAct().getFlag())? "1" : "0");
		actTaskService.complete(budget.getAct().getTaskId(), budget.getAct().getProcInsId(), budget.getAct().getComment(), vars);
	}
	public List<Budget> findAggregateGroupByClassify(Budget budget){
		return dao.findAggregateGroupByClassify(budget);
	}

}
